/* 
 * File:   anglebounder.hpp
 * Author: posypkin
 *
 * Created on July 23, 2012, 11:33 AM
 *
 * The bounder for angular constraint
 * for the last link
 */

#ifndef ANGLEBOUNDER_HPP
#define	ANGLEBOUNDER_HPP

template <class FT> class AngleBounder : public Bounder < FT > {
public:

    /**
     * The constructor
     * @param nangles number of bounded angles
     * @param bounds the array of right parts
     */
    AngleBounder(int nangles, FT* bounds) {
        mNAngles = nangles;
        mBounds = bounds;
    }

    /**
     * Retrieve the lower bounds
     *
     * @param box the box to evaluate the bound
     * @param crit the place to store the lower bounds for criteria (NULL means no bound is needed)
     * @param cons the place to store the lower bounds for constraints (NULL means no bound is needed)
     */
    void getLowerBound(const Box<FT>& box, FT* crit, FT* cons) const {
        int n = box.mDim;
        FT al = 0, au = 0;
        FT phil = 0, phiu = 0;
        for (int i = 0; i < mNAngles; i++)
            cons[i] = 0;
        for (int i = 0; i < n; i++)
            BNBInterval<FT>::sum(phil, phiu, box.mA[i], box.mB[i], &phil, &phiu);

        for (int i = 0; i < mNAngles; i++) {
            if (i % 2 == 0)
                cons[i] = mBounds[i] - phiu;
             else 
                cons[i] = phil - mBounds[i];
            //printf("cons[%d] = %lf\n", i, cons[i]);
        }
    }

private:
    int mNAngles;
    FT* mBounds;
};


#endif	/* ANGLEBOUNDER_HPP */

